package com.lcc.lynx.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

/**
 * Description: IO流操作
 * Project: efp-common-util
 * Company: 中博信息技术研究院有限公司
 * DateTime: 2017年1月5日 上午11:26:56
 *
 * @author dingzhenhua@zbiti.com
 * @version 1.0.0.0
 * @Copyright: Copyright (c) 2017-2026
 */
public class IOUtils {
    private IOUtils() {
    }

    /**
     * 读取文件到IO流
     *
     * @param file
     * @return
     */
    public static byte[] read(File file) {
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        byte[] bs = null;
        try {
            fis = new FileInputStream(file);
            bs = new byte[1024];
            bos = new ByteArrayOutputStream();
            int len = -1;
            while ((len = fis.read(bs)) != -1) {
                bos.write(bs, 0, len);
            }
            bs = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bs;
    }

    /**
     * 输出字节数组到输出流，并关闭输出流
     *
     * @param bytes 字节数组
     * @param os    输出里
     * @throws IOException IO异常
     */
    public static void write(byte[] bytes, OutputStream os) throws IOException {
        write(bytes, os, true);
    }

    /**
     * 输出字节数组到输出流
     *
     * @param bytes       字节数组
     * @param os          输出里
     * @param closeOutput 是否关闭输出流
     * @throws IOException IO异常
     */
    public static void write(byte[] bytes, OutputStream os, boolean closeOutput) throws IOException {
        try {
            os.write(bytes);
            os.flush();
        } finally {
            if (closeOutput && os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 输出字符串到输出流，并关闭输出流
     *
     * @param value 字符串
     * @param os    输出流
     * @throws IOException IO异常
     */
    public static void write(String value, OutputStream os) throws IOException {
        write(value, os, true);
    }

    /**
     * 输出字符串到输出流
     *
     * @param value       字符串
     * @param os          输出里
     * @param closeOutput 是否关闭输出流
     * @throws IOException IO异常
     */
    public static void write(String value, OutputStream os, boolean closeOutput) throws IOException {
        write(value.getBytes(StandardCharsets.UTF_8), os, closeOutput);
    }

    /**
     * 从输入流读取byte数组到输出流，并关闭输入流和输出流
     *
     * @param is 输入流
     * @param os 输出流
     */
    public static void writeBytes(InputStream is, OutputStream os) throws IOException {
        writeBytes(is, os, true, true);
    }

    /**
     * 输出指定文件的byte数组
     *
     * @param is 输入流
     * @param os 输出流
     */
    public static void writeBytes( InputStream is,  OutputStream os, boolean closeInput, boolean closeOutput) throws IOException {
        try {
            byte[] b = new byte[1024];
            int length;
            while ((length = is.read(b)) > 0) {
                os.write(b, 0, length);
            }
        } finally {
            if (closeInput && is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (closeOutput && os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 从输入流读取字节数组，并关闭输入流
     *
     * @param is 输入流程
     * @return 字节数组
     */
    public static byte[] readBytes(InputStream is) throws IOException {
        return readBytes(is, true);
    }

    /**
     * 从输入流读取字节数组
     *
     * @param is         输入流程
     * @param closeInput 是否关闭输入流
     * @return 字节数组
     */
    public static byte[] readBytes( InputStream is, boolean closeInput) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        writeBytes(is, bos, closeInput, true);
        return bos.toByteArray();
    }
}
